package info.aksandbox.bukkit.shirtsandskins;

import com.elmakers.mine.bukkit.plugins.persistence.Persistence;
import com.elmakers.mine.bukkit.plugins.persistence.PersistencePlugin;
import com.elmakers.mine.bukkit.plugins.persistence.PluginUtilities;
import com.elmakers.mine.bukkit.plugins.persistence.dao.PluginCommand;
import java.io.File;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.entity.Player;
import org.bukkit.Server;

import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;




import info.aksandbox.bukkit.akBorderGuard.akBorderGuard;
import org.bukkit.Location;
import org.bukkit.Material;

/**
 * ShirtsAndSkins for Bukkit
 *
 * @author amkeyte
 */
public class ShirtsAndSkins extends JavaPlugin {

    private static final Logger logger = Logger.getLogger("Minecraft");
    private final ShirtsAndSkinsPlayerListener playerListener = new ShirtsAndSkinsPlayerListener(this);
    private final ShirtsAndSkinsBlockListener blockListener = new ShirtsAndSkinsBlockListener(this);
    private final HashMap<Player, Boolean> debugees = new HashMap<Player, Boolean>();
    private Persistence persistence = null;
    private PluginUtilities utilities = null;
    private akBorderGuard _akBorderGuard = null;

    public ShirtsAndSkins(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) {
        super(pluginLoader, instance, desc, folder, plugin, cLoader);
        // TODO: Place any custom initialisation code here

        // NOTE: Event registration should be done in onEnable not here as all events are unregistered when a plugin is disabled
    }

    public void onEnable() {
        PluginManager pm = getServer().getPluginManager();
        Plugin checkForPlugin = pm.getPlugin("Persistence");

        if (checkForPlugin != null) {
            PersistencePlugin plugin = (PersistencePlugin) checkForPlugin;
            persistence = plugin.getPersistence();
        } else {
            log(Level.WARNING, "Persistence is required. Disabling SkinsandShirts.");
            pm.disablePlugin(this);
        }

        //set up akBorderGuard
        checkForPlugin = pm.getPlugin("akBorderGuard");
        if (_akBorderGuard == null
                && checkForPlugin != null) {
            _akBorderGuard = (akBorderGuard) checkForPlugin;
        } else {
            log(Level.WARNING, "akBorderGuard plugin is required. Disabling SkinsandShirts.");
            pm.disablePlugin(this);
        }



        // Register events

        PluginCommand generalCommand = utilities.getGeneralCommand(
                "ss",
                "SkinsAndShirts",
                "ss <help|build|team|teamleader|phase|border|pause>");
        generalCommand.bind("onGeneralCommand");

        PluginCommand help = generalCommand.getSubCommand("help", "Show SkinsAndShirts help", "ss help");
        help.bind("onCommandHelp");
        PluginCommand build = generalCommand.getSubCommand("build", "Install SkinsAndShirts fixtures", "ss build <help|spawn|pagoda>");
        build.bind("onCommandBuild");
        build.addUsage("ss build base <skins|shirts>");
        PluginCommand team = generalCommand.getSubCommand("team", "Assign a player to a team", "ss team <player> <skins|shirts|observers>");
        team.bind("onCommandTeam");
        team.addUsage("team help");
        PluginCommand teamleader = generalCommand.getSubCommand("teamleader", "Assign a player as a team leader", "ss teamleader <player> <skins|shirts>");
        teamleader.bind("onCommandTeamleader");
        teamleader.addUsage("teamleader help");
        PluginCommand phase = generalCommand.getSubCommand("phase", "set the SkinsAndShirts game phase", "ss phase <help|generate|explore|mine|pvp|raid|talley|post>");
        phase.bind("onCommandPhase");
        PluginCommand border = generalCommand.getSubCommand("border", "set the server border", "ss border <help|distance_from_player>");
        border.bind("onCommandBorder");

        //enable complete
        PluginDescriptionFile pdfFile = this.getDescription();
        log(Level.INFO, "version " + pdfFile.getVersion() + " is enabled!");
    }

    public boolean onGeneralCommand(CommandSender sender, PluginCommand command, String commandLabel, String[] args) {
        if (!checkPermissions(sender, "skinsandshirts")) {
            return true;
        }

        command.sendHelp(sender, "", true, true);
        return true;
    }

    public boolean onCommandHelp(CommandSender sender, PluginCommand command, String commandLabel, String[] args) {
        if (!checkPermissions(sender, "skinsandshirts")) {
            return true;
        }
        sender.sendMessage("SkinsAndShirts Bukkit Plugin is an admin tool that allows you to control the Skins and Shirts gameplay.");
        sender.sendMessage("The following commands are available:");
        command.getParent().sendHelp(sender, "", true, false); //still showing subs?
        sender.sendMessage("Type the word 'help' after any command to see more.");

        return true;
    }

    public boolean onCommandBuild(CommandSender sender, PluginCommand command, String commandLabel, String[] args) {
        //"ss build <help|spawn|pagoda|base>"
        if (!checkPermissions(sender, "skinsandshirts.build")) {
            return true;
        }
        if (!checkCommandArgs(args) || args[0].equalsIgnoreCase("help")) {

            command.sendHelp(sender, "", true, true);
        } else if (args[0].equalsIgnoreCase("spawn")) {
            if (!checkPermissions(sender, "skinsandshirts.build.spawn")) {
                return true;
            }
            sender.sendMessage("Building spawn area");
        } else if (args[0].equalsIgnoreCase("pagoda")) {
            if (!checkPermissions(sender, "skinsandshirts.build.pagoda")) {
                return true;
            }
            sender.sendMessage("Building pagoda");
        } else if (args.length == 2) {
            if (args[0].equalsIgnoreCase("base")) {
                if (args[1].equalsIgnoreCase("skins")) {
                    if (!checkPermissions(sender, "skinsandshirts.build.base.skins")) {
                        return true;
                    }
                    sender.sendMessage("Building base for " + args[1]);
                } else if (args[1].equalsIgnoreCase("shirts")) {
                    if (!checkPermissions(sender, "skinsandshirts.build.base.shirts")) {
                        return true;
                    }
                    sender.sendMessage("Building base for " + args[1]);
                } else {
                    //failed two parameter command
                    command.sendHelp(sender, "", true, true);
                }
            }
        } else {
            //failed single paramerer command
            command.sendHelp(sender, "", true, true);
        }

        return true;
    }

    public boolean onCommandTeam(CommandSender sender, PluginCommand command, String commandLabel, String[] args) {
        //ss team <player> <skins|shirts|observers>
        if (!checkPermissions(sender, "skinsandshirts.team")) {
            return true;
        }

        if (!checkCommandArgs(args)) {
            //no args
            command.sendHelp(sender, "", true, true);
        } else if (args[0].equalsIgnoreCase("help")) {
            //do specific help stuff here
            command.sendHelp(sender, "", true, true);
        } else if (args.length == 2) {
            if (args[1].equalsIgnoreCase("skins")) {
                if (!checkPermissions(sender, "skinsandshirts.team.skins")) {
                    return true;
                }
                sender.sendMessage("adding " + args[0] + " to team: " + args[1]);
            } else if (args[1].equalsIgnoreCase("shirts")) {
                if (!checkPermissions(sender, "skinsandshirts.team.shirts")) {
                    return true;
                }
                sender.sendMessage("adding " + args[0] + " to team: " + args[1]);
            } else if (args[1].equalsIgnoreCase("observers")) {
                if (!checkPermissions(sender, "skinsandshirts.team.observers")) {
                    return true;
                }
                sender.sendMessage("adding " + args[0] + " to team: " + args[1]);
            } else {
                //bad command two params
                command.sendHelp(sender, "", true, true);
            }
        } else {
            //command has a typo or something.. send help!
            command.sendHelp(sender, "", true, true);
        }
        return true;
    }

    public boolean onCommandTeamleader(CommandSender sender, PluginCommand command, String commandLabel, String[] args) {
        //ss teamleader <player> <skins|shirts>
        if (!checkPermissions(sender, "skinsandshirts.teamleader")) {
            return true;
        }
        if (!checkCommandArgs(args)) {
            //no args sent
            command.sendHelp(sender, "", true, true);
        } else if (args[0].equalsIgnoreCase("help")) {
            //do specific help stuff here
            command.sendHelp(sender, "", true, true);
        } else if (args.length == 2) {
            if (args[1].equalsIgnoreCase("skins")) {
                sender.sendMessage("adding " + args[0] + " to teamleaders of team: " + args[1]);
            } else if (args[1].equalsIgnoreCase("shirts")) {
                sender.sendMessage("adding " + args[0] + " to teamleaders of team: " + args[1]);
            } else {
                //two param type
                command.sendHelp(sender, "", true, true);
            }
        } else {
            //command has a typo or something.. send help!
            command.sendHelp(sender, "", true, true);
        }
        return true;


    }

    public boolean onCommandPhase(CommandSender sender, PluginCommand command, String commandLabel, String[] args) {
        //ss phase <help|generate|explore|mine|pvp|raid|talley|post>
        if (!checkPermissions(sender, "skinsandshirts.phase")) {
            return true;
        }

        if (!checkCommandArgs(args)) {
            command.sendHelp(sender, "", true, true);
        } else if (args[0].equalsIgnoreCase("help")) {
            //do specific help stuff here
            command.sendHelp(sender, "", true, true);
        } else if (args.length == 1) {
            sender.sendMessage("Setting phase to: " + args[0]);
        } else {
            //command has a typo or something.. send help!
            command.sendHelp(sender, "", true, true);
        }
        return true;
    }

    public boolean onCommandBorder(CommandSender sender, PluginCommand command, String commandLabel, String[] args)
            throws Exception {
        //ss border <help|distance_from_player>
        if (!checkPermissions(sender, "skinsandshirts.border")) {
            return true;
        }
        if (!checkCommandArgs(args)) {
            command.sendHelp(sender, "", true, true);
        } else if (args[0].equalsIgnoreCase("help")) {
            //do specific help stuff here
            command.sendHelp(sender, "", true, true);
        } else if (args.length == 1) {
            String borderSize = args[0];
            Material wallMaterial = Material.getMaterial(Integer.valueOf(args[1]));
            Location location = null;
            String worldName = null;
            if (sender instanceof Player) {
                sender.sendMessage("Setting border to: " + borderSize);
                location = ((Player) sender).getLocation();
                worldName = ((Player) sender).getWorld().getName();
            } else if (sender instanceof ConsoleCommandSender) {
                sender.sendMessage("Please log in to set the border.");
                return true;
            }
            try {
                _akBorderGuard.setBorder(sender, location, worldName, Integer.valueOf(borderSize), wallMaterial);
            } catch (akBorderGuard.akBorderGuardException e) {
                sender.sendMessage(e.toString());
            }
        } else {
            //command has a typo or something.. send help!
            command.sendHelp(sender, "", true, true);
        }
        return true;
    }

    private boolean checkCommandArgs(String[] args) {
        if (args != null && args.length > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
        return utilities.dispatch(this, sender, cmd.getName(), args);
    }

    public void onDisable() {
        // TODO: Place any custom disable code here

        // NOTE: All registered events are automatically unregistered when a plugin is disabled

        // EXAMPLE: Custom code, here we just output some info so we can check all is well
        log(Level.INFO, "is disabled!");
    }

    public boolean isDebugging(final Player player) {
        if (debugees.containsKey(player)) {
            return debugees.get(player);
        } else {
            return false;
        }
    }

    public void setDebugging(final Player player, final boolean value) {
        debugees.put(player, value);
    }

    static void log(Level level, String msg) {
        logger.log(level, "[ShirtsAndSkins] ".concat(msg));
    }

    static boolean checkPermissions(CommandSender sender, String perm) {
        if (sender instanceof Player) {
            log(Level.SEVERE, "FIX PERMISSIONS");
            return true;

        } else if (sender instanceof ConsoleCommandSender) {
            return true;
        }
        sender.sendMessage("Permission Denied");
        return false;
    }
}
